package com.biz.primus.ms.order.service.helper;

import com.biz.primus.base.exception.BizSilentException;
import com.biz.primus.base.exception.utils.AssertUtils;
import com.biz.primus.model.oms.stream.OrderStateChannel;
import com.biz.primus.model.oms.vo.UserOrderOperationRequest;
import com.biz.primus.model.order.enums.DeliveryState;
import com.biz.primus.model.order.enums.OrderState;
import com.biz.primus.model.order.exception.OrderException;
import com.biz.primus.ms.order.convertor.OmsOrderConvertor;
import com.biz.primus.ms.order.dao.po.Order;
import com.biz.primus.ms.order.dao.repository.OrderRepository;
import com.biz.primus.ms.order.feign.OmsFeignClient;
import com.biz.primus.ms.order.stream.OrderStateSink;
import com.biz.primus.ms.order.stream.OrderStateSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;

/**
 * 订单状态消息助理<br><p>
 * 接收OMS的出库订单；
 * 接收OMS的取消订单；
 * 接收OMS的确认收货订单；
 * 推送用户确认收货订单给OMS；
 * </p>
 *
 * @author Tiger Feng
 * @date 2017年11月23日
 */
@Service
public class OrderStateStreamHelper {
    @Autowired
    private OrderStateSource orderStateSource;
    //=========================================
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private OmsFeignClient omsService;

    /**
     * 接收出库订单
     *
     * @param orderStreamDataMessage 订单信息
     */
    @StreamListener(OrderStateSink.ORDER_OUTBOUND)
    public void receiveOutboundOrder(Message<OrderStateChannel.OrderStreamData> orderStreamDataMessage) {
        // 订单状态：待收货
        // 物流状态：配送中
        // 评价状态：空，不做修改
        OrderStateChannel.OrderStreamData orderStreamData = orderStreamDataMessage.getPayload();
        // 订单发货
        Order order = orderRepository.findByOrderCode(orderStreamData.getOrderCode());
        AssertUtils.notNull(order, OrderException.ORDER_NOT_EXIST);
        // 支付状态
        switch (order.getPaymentState()) {
            case PAY_ON_DELIVERY:
                // 货到付款
                break;
            case WAIT_PAY:
                // 待付款
                throw new BizSilentException(OrderException.PLEASE_PAY);
            case PAY_FAILURE:
                throw new BizSilentException(OrderException.PLEASE_PAY);
            case PAY_SUCCESS:
                break;
            default:
                throw new BizSilentException(OrderException.NO_SUPPORT_PAYMENT_STATE);
        }
        // 订单状态
        switch (order.getState()) {
            case WAIT_SEND:
                break;
            default:
                throw new BizSilentException(OrderException.STATE_ERROR);
        }
        // 物流状态
        switch (order.getDelivery().getDeliveryState()) {
            case FOR_OUTBOUND:
                // 订单状态 -> 待收货
                order.setState(OrderState.WAIT_RECEIVE);
                break;
            case FOR_TAKE_THEIR:
                // 自提
                break;
            default:
                throw new BizSilentException(OrderException.DELIVERY_STATE_ERROR);
        }
        // 物流状态 -> 待发货
        order.getDelivery().setDeliveryState(DeliveryState.DISTRIBUTING);
        // 评价状态 -> null
        order.setCommentState(null);
        Timestamp now = new Timestamp(System.currentTimeMillis());
        order.setUpdateTimestamp(now);
        orderRepository.save(order);
    }

    /**
     * 接收中台取消订单
     *
     * @param orderStreamDataMessage
     */
    @StreamListener(OrderStateSink.ORDER_CANCEL)
    public void receiveCancelOrder(Message<OrderStateChannel.OrderStreamData> orderStreamDataMessage) {
        // 订单状态：已取消
        // 物流状态：待出库
        // 评价状态：空，不做修改
        Order order = orderRepository.findByOrderCode(orderStreamDataMessage.getPayload().getOrderCode());
        AssertUtils.notNull(order, OrderException.ORDER_NOT_EXIST);
        order.setState(OrderState.CANCELED);
        Timestamp now = new Timestamp(System.currentTimeMillis());
        order.setUpdateTimestamp(now);
        orderRepository.save(order);
    }

    /**
     * 接收用户确认收货(自提或者门店送货完成时，OMS通知前端订单用户已收货)
     *
     * @param orderStreamDataMessage
     */
    @StreamListener(OrderStateSink.ORDER_FINISHED)
    public void receiveFinishOrder(Message<OrderStateChannel.OrderStreamData> orderStreamDataMessage) {
        Order order = orderRepository.findByOrderCode(orderStreamDataMessage.getPayload().getOrderCode());
        AssertUtils.notNull(order, OrderException.ORDER_NOT_EXIST);
        // 物流状态
        switch (order.getDelivery().getDeliveryState()) {
            case DISTRIBUTING:
                break;
            case FOR_TAKE_THEIR:
                break;
            case SIGNED:
                // 已签收了，不用再次确认收货
                return;
            case PART_OF_SIGNED:
                break;
            case REJECT:
                break;
            default:
                throw new BizSilentException(OrderException.DELIVERY_STATE_ERROR);
        }
        // 订单状态
        switch (order.getState()) {
            case FINISHED:
                // 订单已完成，不用再次确认收货
                return;
            case WAIT_RECEIVE:
                break;
            default:
                throw new BizSilentException(OrderException.STATE_ERROR);
        }
        order.getDelivery().setDeliveryState(DeliveryState.SIGNED);
        order.setState(OrderState.FINISHED);
        Timestamp now = new Timestamp(System.currentTimeMillis());
        order.setUpdateTimestamp(now);
        orderRepository.save(order);
    }

    /**
     * 发送用户确认收货 -- 接口
     *
     * @param order 订单
     */
    public void sendUserFinishOrder(Order order) {
        switch (order.getState()) {
            case FINISHED:
                UserOrderOperationRequest vo = OmsOrderConvertor.getOmsOrderOperationRequestVoFromPo(order);
                omsService.confirmReceive(vo);
                break;
            default:
                throw new BizSilentException(OrderException.STATE_ERROR);
        }
    }

    /**
     * 发送用户取消订单(仅限"货到付款") -- 接口
     *
     * @param order
     */
    public void sendUserCancelOrder(Order order) {
        switch (order.getState()) {
            case CANCELED:
                UserOrderOperationRequest vo = OmsOrderConvertor.getOmsOrderOperationRequestVoFromPo(order);
                omsService.cancelOrder(vo);
                break;
            default:
                throw new BizSilentException(OrderException.STATE_ERROR);
        }
    }
}
